package org.example.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NettySocketServer extends Thread {

  private static final Logger logger = LoggerFactory.getLogger(NettySocketServer.class);

  private final int port;

  public NettySocketServer(int port) throws IOException {
    this.port = port;
  }

  @Override
  public void run() {
    logger.info("NettySocketServer Start port:{}", port);
    try {
      ServerBootstrap b = new ServerBootstrap();
      NioEventLoopGroup group = new NioEventLoopGroup();
      b.group(group)
          .channel(NioServerSocketChannel.class)
          .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch)
                throws Exception {
              System.out.println("initChannel ch:" + ch);
              ch.pipeline()
                  .addLast("decoder", new HttpRequestDecoder())
                  .addLast("encoder", new HttpResponseEncoder())
                  .addLast("aggregator", new HttpObjectAggregator(512 * 1024))
                  .addLast("handler", new HttpHandler());
            }
          })
          .option(ChannelOption.SO_BACKLOG, 128)
          .childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE);

      b.bind(port).sync();
    }
    catch (Exception e) {
      logger.error("NettySocketServer ERROR", e);
    }

  }

}
